import * as React from 'react';
import type { ButtonHTMLType, ButtonShape, ButtonType } from './buttonHelpers';
import { ConfigContext } from '../config-provider';
import classNames from 'classnames';
import LoadingIcon from './LoadingIcon';
import type { SizeType } from '../config-provider/SizeContext';
import SizeContext from '../config-provider/SizeContext';
export interface BaseButtonProps {
  type?: ButtonType;
  icon?: React.ReactNode;
  children?: React.ReactNode;
  shape?: ButtonShape;
  ghost?: boolean;
  disabled?: boolean;
  danger?: boolean;
  loading?: boolean | { delay?: number };
  size?: SizeType;
}

export type AnchorButtonProps = {
  href: string;
  target?: string;
  onClick?: React.MouseEventHandler<HTMLAnchorElement>;
} & BaseButtonProps &
  Omit<
    React.AnchorHTMLAttributes<HTMLAnchorElement | HTMLButtonElement>,
    'type' | 'onclick'
  >;

export type NativeButtonProps = {
  htmlType?: ButtonHTMLType;
  onClick?: React.MouseEventHandler<HTMLButtonElement>;
} & BaseButtonProps &
  Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type' | 'onClcik'>;

export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;

type LoadingConfigType = {
  loading: boolean;
  delay: number;
};

function getLoadingConfig(
  loading: BaseButtonProps['loading'],
): LoadingConfigType {
  if (typeof loading === 'object' && loading) {
    const delay = loading?.delay;
    const isDelay = !Number.isNaN(delay) && typeof delay === 'number';
    return {
      loading: false,
      delay: isDelay ? delay : 0,
    };
  }
  return {
    loading: !!loading,
    delay: 0,
  };
}

type Loading = number | boolean;
const InternalButton: React.ForwardRefRenderFunction<
  HTMLButtonElement,
  ButtonProps
> = (props, ref) => {
  const {
    type = 'default',
    htmlType = 'button',
    shape = 'default',
    ghost = false,
    disabled = false,
    danger,
    icon,
    loading = false,
    children,
    size: customizeSize,
    ...rest
  } = props;
  //  处理样式
  const { getPrefixCls } = React.useContext(ConfigContext);
  const prefixCls = getPrefixCls('btn');
  // size

  const size = React.useContext(SizeContext);
  const sizeClassNameMap = {large: 'lg', small: 'sm', middle: undefined};
  const sizeFullname = customizeSize || size;
  const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';
  // loading
  const loadingOrDelay: LoadingConfigType = React.useMemo(
    () => getLoadingConfig(loading),
    [loading],
  );
  const [innerLoading, setLoading] = React.useState<Loading>(
    loadingOrDelay.loading,
  );
  const iconType = innerLoading ? 'loading' : icon;

  const classes = classNames(prefixCls, {
    [`${prefixCls}-${shape}`]: shape !== 'default' && shape,
    [`${prefixCls}-${type}`]: type,
    [`${prefixCls}-background-ghost`]: ghost,
    [`${prefixCls}-disabled`]: props.disabled,
    [`${prefixCls}-dangerous`]: !!danger,
    [`${prefixCls}-${sizeCls}`]: sizeCls,
  });

  const iconNode =
    icon && !innerLoading ? (
      icon
    ) : (
      <LoadingIcon
        existIcon={!!icon}
        prefixCls={prefixCls}
        loading={!!innerLoading}
      />
    );

  const kids = children;

  const buttonNode = (
    <button className={classes} type={htmlType} disabled={props.disabled} {...rest}>
      {iconNode}
      {props.children}
    </button>
  );
  return buttonNode;
};

const Button = React.forwardRef(InternalButton);

export default Button;
